package com.msi.gui;



import java.awt.geom.Point2D;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.logging.Level;

import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;

public class FileWorker {

	protected static final Logger log = Logger.getLogger(FileWorker.class);
	
	private static File file;
	private static BufferedReader inputStream;
	private static FileInputStream fis;
	
	public static List<List<Integer>> extractNeighbourList(String fileName) {
		boolean rootIsConfigured = Logger.getRootLogger().getAllAppenders().hasMoreElements();
	      if (!rootIsConfigured) 
	         BasicConfigurator.configure();
		
		ArrayList<List<Integer>> neighbourMatrix = new ArrayList<List<Integer>>();
		
		openFile(fileName);
		return readGraph(fileName, neighbourMatrix);
	
	}
	
	public static List<List<Integer>> extractNeighbourList(File selectedFile) {
		boolean rootIsConfigured = Logger.getRootLogger().getAllAppenders().hasMoreElements();
                if (!rootIsConfigured) 
                    BasicConfigurator.configure();
		List<List<Integer>> neighbourMatrix = new ArrayList<List<Integer>>();
		
		file = selectedFile;
		log.info("wtf");
		return readGraph(selectedFile.getName(), neighbourMatrix);
		
	}
        
        
        public static Map<Integer, Point2D> extractCoordinatesFromFile(File selectedFile){
        FileInputStream fis = null;
        try {
            fis = new FileInputStream(file);
            BufferedReader inputStream = new BufferedReader(new InputStreamReader(fis));
            String line = "";
            boolean foundCoordinates = false;
            while((line = inputStream.readLine()) != null){
                if("coordinates".equals(line.trim())) {
                    foundCoordinates = true;
                    break;
                }
            }
			Map<Integer, Point2D> map = new HashMap<Integer, Point2D>();
            if(foundCoordinates){
                while((line = inputStream.readLine()) != null){
                     StringTokenizer tokenizer = new StringTokenizer(line);
                     log.debug("Wczytano linie, ilosc elementow: "+tokenizer.countTokens());
                     if(tokenizer.countTokens() != 3 ) {
                         log.error("Probujemy odczytac wspolzedne ale jedna linijka wspolzednych zawiera zbyt malo danych, dlatego wczytanie wspolzednych jset anulowane");
                         continue;
                     }
                     int id = -1;
                     float longi = -1;
                     float latt = -1;
                     while(tokenizer.hasMoreTokens()){
                         if(id == -1){   
                            id = Integer.parseInt(tokenizer.nextToken()); 
                        }
                         else if(longi < 0 ){
                            longi = Float.parseFloat(tokenizer.nextToken()); 
                        }
                         else if(latt < 0) {
                             latt = Float.parseFloat(tokenizer.nextToken());
                             map.put(id, new Point2D.Double(longi, latt));
                        }
                         
                     
                }
            }
                return map;
            }
            return null;
            
        } catch (IOException ex) {
            java.util.logging.Logger.getLogger(FileWorker.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }  finally {
            try {
                fis.close();
            } catch (IOException ex) {
                java.util.logging.Logger.getLogger(FileWorker.class.getName()).log(Level.SEVERE, null, ex);
                return null;
            }
            
        }
        } 

	private static List<List<Integer>> readGraph(String fileName,
		List<List<Integer>> neighbourMatrix) {
		try {
			long start=System.currentTimeMillis();
				log.debug("otwieranie strumieni");
				openDataInputStream();
				readGraphToList(neighbourMatrix);
				//drawNeighbourMatrix(neighbourMatrix);
			long stop=System.currentTimeMillis();
			log.info("wczytywania grafu z pliku do listy:"+(stop-start));
			
		} catch (FileNotFoundException e) {
			log.error("Nie udalo sie otworzyc strumienia na pliku: "+fileName);
			return null;
		} catch (IOException e) {
			log.error("cos sie zjebalo przy odczytywaniu pliku: "+fileName);
			e.printStackTrace();
			return null;
		}
		return neighbourMatrix;
	}
	

	private static void drawNeighbourMatrix(List<List> neighbourMatrix) {
		log.info("Wczytano maciez sasiedztwa:");
		for(int i=0; i<neighbourMatrix.size(); ++i){
			for(int j=0; j<neighbourMatrix.get(i).size(); ++j)
				System.out.print(" '"+neighbourMatrix.get(i).get(j)+"'");
			System.out.println("");
		}
	}

	private static void readGraphToList(List<List<Integer>> neighbourMatrix) throws IOException {
		String line = "";
		while((line = inputStream.readLine()) != null){
		 StringTokenizer tokenizer = new StringTokenizer(line);
		 //log.debug("Wczytano linie, ilosc elementow: "+tokenizer.countTokens());
		 List<Integer> list = new ArrayList<Integer>();
                 if("coordinates".equals(line.trim()) || line.isEmpty()) {
                     return;
                 }
		 while(tokenizer.hasMoreTokens()){
			list.add(Integer.parseInt(tokenizer.nextToken())); 
		 }
		 neighbourMatrix.add(list);
		}
	}

	private static void openDataInputStream() throws FileNotFoundException {
		fis = new FileInputStream(file);
		inputStream = new BufferedReader(new InputStreamReader(fis));		
	}

	private static void openFile(String fileName) {
		file = new File(fileName);
	}


}
